{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "12058891",
   "metadata": {},
   "source": [
    "\n",
    "# 采用变分算法重构半导体双量子点单-三重态 普适双比特量子门\n",
    "\n",
    "变分线路构建"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5cf7200",
   "metadata": {},
   "source": [
    "采用变强度，不变持续时间的脉冲。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "dedea826",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "进度: 10/10  acc: 0.978467316260791\n",
      "平均保真度为： 0.8834858305115736\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from numpy import kron\n",
    "from mindquantum import *\n",
    "from scipy.linalg import expm\n",
    "import mindspore as ms\n",
    "from mindspore import ops\n",
    "ms.context.set_context(mode=ms.context.PYNATIVE_MODE, device_target=\"CPU\")\n",
    "from mindspore.nn import Adam, TrainOneStepCell\n",
    "from mindspore.common.parameter import Parameter\n",
    "from mindspore.common.initializer import initializer  \n",
    "ms.set_seed(1)\n",
    "np.random.seed(1)\n",
    "\n",
    "train_x = np.load('./src/2_qubit_train_x.npy', allow_pickle=True)\n",
    "eval_x = np.load('./src/2_qubit_eval_x.npy', allow_pickle=True)\n",
    "train_y = np.load('./src/2_qubit_train_y.npy', allow_pickle=True)\n",
    "eval_y = np.load('./src/2_qubit_eval_y.npy', allow_pickle=True)\n",
    "u_mats = np.load('./src/2_qubit_u.npy', allow_pickle=True)\n",
    "\n",
    "s_x = X.matrix()\n",
    "s_z = Z.matrix()\n",
    "one = I.matrix()\n",
    "dt = np.pi/10\n",
    "\n",
    "def _matrix_0(coeff):\n",
    "    return expm(-1j*(coeff*s_z+s_x)*dt)\n",
    "\n",
    "def _diff_matrix_0(coeff):\n",
    "    return -1j*_matrix_0(coeff)@(s_z*dt)\n",
    "\n",
    "def _matrix_c_0(coeff):\n",
    "    return expm(-1j*(coeff*kron(s_z, one) + kron(one, s_z) + kron(s_x, one) + kron(one, s_x) + coeff*kron(s_z-one, s_z-one))*dt)\n",
    "\n",
    "def _diff_matrix_c_0(coeff):\n",
    "    return -1j*_matrix_c_0(coeff)@((kron(s_z, one) + kron(s_z-one, s_z-one)) * dt)\n",
    "\n",
    "def _matrix_c_1(coeff):\n",
    "    return expm(-1j*(kron(s_z, one) + coeff*kron(one, s_z) + kron(s_x, one) + kron(one, s_x) + coeff*kron(s_z-one, s_z-one))*dt)\n",
    "\n",
    "def _diff_matrix_c_1(coeff):\n",
    "    return -1j*_matrix_c_1(coeff)@((kron(one, s_z) + kron(s_z-one, s_z-one)) * dt)\n",
    "\n",
    "gate_0 = gene_univ_parameterized_gate('gete_0', _matrix_0, _diff_matrix_0)\n",
    "gate_c_0 = gene_univ_parameterized_gate('gete_c_0', _matrix_c_0, _diff_matrix_c_0)\n",
    "gate_c_1 = gene_univ_parameterized_gate('gete_c_1', _matrix_c_1, _diff_matrix_c_1)\n",
    "\n",
    "circ = Circuit()\n",
    "circ += gate_0('00').on(0)\n",
    "circ += gate_0('01').on(0)\n",
    "circ += gate_0('02').on(0)\n",
    "circ += gate_0('03').on(0)\n",
    "circ += gate_0('04').on(0)\n",
    "circ += gate_0('05').on(0)\n",
    "\n",
    "circ += gate_0('10').on(1)\n",
    "circ += gate_0('11').on(1)\n",
    "circ += gate_0('12').on(1)\n",
    "circ += gate_0('13').on(1)\n",
    "circ += gate_0('14').on(1)\n",
    "circ += gate_0('15').on(1)\n",
    "\n",
    "circ += gate_c_0('0').on([1,0])\n",
    "\n",
    "circ += gate_0('06').on(0)\n",
    "circ += gate_0('07').on(0)\n",
    "circ += gate_0('08').on(0)\n",
    "circ += gate_0('09').on(0)\n",
    "circ += gate_0('010').on(0)\n",
    "circ += gate_0('011').on(0)\n",
    "\n",
    "circ += gate_0('16').on(1)\n",
    "circ += gate_0('17').on(1)\n",
    "circ += gate_0('18').on(1)\n",
    "circ += gate_0('19').on(1)\n",
    "circ += gate_0('110').on(1)\n",
    "circ += gate_0('111').on(1)\n",
    "\n",
    "# circ += gate_c_0('1').on([1,0])\n",
    "\n",
    "# circ += gate_0('012').on(0)\n",
    "# circ += gate_1('013').on(0)\n",
    "# circ += gate_0('014').on(0)\n",
    "# circ += gate_1('015').on(0)\n",
    "# circ += gate_0('016').on(0)\n",
    "# # circ += gate_1('017').on(0)\n",
    "\n",
    "# circ += gate_0('112').on(1)\n",
    "# circ += gate_1('113').on(1)\n",
    "# circ += gate_0('114').on(1)\n",
    "# circ += gate_1('115').on(1)\n",
    "# circ += gate_0('116').on(1)\n",
    "# # circ += gate_1('117').on(1)\n",
    "\n",
    "circ += gate_c_1('2').on([1,0])\n",
    "\n",
    "circ += gate_0('018').on(0)\n",
    "circ += gate_0('019').on(0)\n",
    "circ += gate_0('020').on(0)\n",
    "circ += gate_0('021').on(0)\n",
    "circ += gate_0('022').on(0)\n",
    "circ += gate_0('023').on(0)\n",
    "\n",
    "circ += gate_0('118').on(1)\n",
    "circ += gate_0('119').on(1)\n",
    "circ += gate_0('120').on(1)\n",
    "circ += gate_0('121').on(1)\n",
    "circ += gate_0('122').on(1)\n",
    "circ += gate_0('123').on(1)\n",
    "\n",
    "ham = Hamiltonian(QubitOperator('')) \n",
    "sim = Simulator('projectq', circ.n_qubits)\n",
    "sim_left = Simulator('projectq',circ.n_qubits)\n",
    "\n",
    "grad_ops = sim.get_expectation_with_grad(ham,\n",
    "                                         circ,\n",
    "                                         circ_left=Circuit(),\n",
    "                                         simulator_left=sim_left,\n",
    "                                         ansatz_params_name=circ.params_name)\n",
    "\n",
    "acc_list = []\n",
    "lr = 0.05\n",
    "for i in range(len(u_mats)):\n",
    "    params = 2*np.pi* np.random.rand(len(circ.params_name))\n",
    "    for j in range(len(train_x)):\n",
    "        f, g = grad_ops(params, train_x[j], train_y[i,j])\n",
    "        params = abs(params + lr * np.squeeze(g).real)\n",
    "        \n",
    "    final_state = []\n",
    "    for j in range(len(eval_x)):\n",
    "        sim.reset()\n",
    "        sim.set_qs(eval_x[j])\n",
    "        sim.apply_circuit(circ, params)\n",
    "        final_state.append(sim.get_qs())\n",
    "        \n",
    "    acc = np.real(np.mean([np.abs(np.vdot(bra, ket)) for bra, ket in zip(np.array(final_state), eval_y[i])]))\n",
    "    acc_list.append(acc)\n",
    "    print(\"\\r\", end=\"\")\n",
    "    print(f\"进度: {i+1}/{len(u_mats)} \",  'acc:', acc, end=\"\")\n",
    "    \n",
    "print('\\n平均保真度为：', np.mean(acc_list))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
